package com.gm.wj.redis;

import com.gm.wj.entity.PtCaptain;
import com.gm.wj.entity.PtMember;
import com.gm.wj.entity.SysFlow;
import com.gm.wj.entity.SysOrder;
import com.gm.wj.service.AliPayService;
import com.gm.wj.service.PtService;
import com.gm.wj.service.SysOrderFlowService;
import com.gm.wj.util.UUidUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * @program: wj
 * @description: Redis监听方法  Redis密钥过期侦听器
 * @author: Huang_shengjun
 * @create: 2020-11-15 22:01
 **/
@Slf4j
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    @Autowired
    SysOrderFlowService sysOrderFlowService;
    @Autowired
    PtService ptService;
    @Autowired
    AliPayService aliPayService;

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * 监听到失效的数据便执行以下方法
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {

        // 获取过期的key
        // String expireKey = new String(message.getBody());  跟下面方法同样
        // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
        String expiredKey = message.toString();
        String key = expiredKey.substring(expiredKey.indexOf(":")+1);

//        log.info("Redis监听到失效的数据expiredKey-->" + expiredKey);
        log.info("【Redis监听】失效的数据expiredKey中取得的值-->" + key);

        /**
         * 支付的订单，如果超时未支付，就操作：
         *   1.设置订单为失败
         *   2.释放库存1个
         */
        SysOrder sysOrder = sysOrderFlowService.findSysOrderByOrderId(key);
        if(sysOrder != null && sysOrder.getOrderStatus() == 0){
            // 修改订单支付状态为失败
            log.info("【Redis】过期的订单查询到了！ -- >" + sysOrder.toString());
            try {
                // 设置订单状态为 2  已失效
                // log.info("过期的【单独购买】订单已经在处理了，变更状态为：2（失效）{}",sysOrder.toString());
                sysOrderFlowService.setStatusByOrder(2, sysOrder);
                // 归还库存  -->  1个库存
                int flag = ptService.findPtCaptainCountByOrderId(key);
                if (flag == 0){
                    log.info("【支付宝订单-单独购买】确定是过期的【单独购买】订单,释放库存1个");
                    ptService.releaseStock(sysOrder.getProductId(),1);
                } else if (flag == 1) {
                    log.info("【支付宝订单-拼团购买】确定是过期的【拼团购买】订单,释放库存3个");
                    ptService.releaseStock(sysOrder.getProductId(),3);
                }
                if (ptService.findMemberByOrderId(key) != null) {
                    log.info("【支付宝订单-参团购买】进来了，");
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                e.printStackTrace();
            }
        }

        /**
         * 发起拼团的订单。如果状态为 0 未付款  或者为 1 还在拼团中  ，直接设置为拼团失败
         * 拼团购买的发起拼团订单，如超时未支付
         */
        PtCaptain ptCaptain = ptService.findByFatherId(key);
        if(ptCaptain != null && ptCaptain.getPtStatus() != 2 ){
            // 修改订单支付状态为失败
            log.info("【Redis】过期的拼团订单查询到了！ -- >" + ptCaptain.toString());
            try {
                //  0:未付款 1:拼团中，2:拼团成功, 3：拼团失败  设置状态为 3  拼团失败
                ptService.setPtCaptainStatus(ptCaptain.getId(),3);
                // 拼团失败，归还库存  -->  3个库存
                ptService.releaseStock(ptCaptain.getProductId(),3);
                log.info("【拼团】 {} 未满团 ，过期的【拼团订单】已经在处理了，变更状态为：3 （拼团失败）并团长退款",ptCaptain.getProductId());
                // 发起退款
                log.info("退款的拼团信息：{}",ptCaptain.toString());
                aliRefundTuikuan(ptCaptain.getOrderId());

                // 参团的订单，如果还未付款或者拼团失败，参团也失败
                List<PtMember> ptMemberList = ptService.findChildrenByFatherId(ptCaptain.getFatherId());
                for (PtMember ptMember : ptMemberList) {
                    log.info("退款的参团信息：{}",ptMember.toString());
                    if (ptMember.getPtStatus() == 1){
                        log.info("【参团】{} 未满团 ，有 {} 个参团的 {} 订单ID 过期的参团订单已经在处理了，变更状态为2（超时）并团员退款",ptMember.getProductId(),ptMemberList.size(),ptMember.getOrderId());
                        // 发起退款
                        aliRefundTuikuan(ptMember.getOrderId());
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                e.printStackTrace();
            }
        }

        /**
        // 参团的订单，如果还未付款或者拼团失败，参团也失败
        PtMember ptMember = ptService.findByChildrenId(key);
        if(ptMember != null && (ptMember.getPtStatus() == 0 || ptCaptain.getPtStatus() == 3)){
            // 修改订单支付状态为失败
             log.info("【Redis】过期的参团订单查询到了！ -- >" + ptMember.toString());
            try {
                // 0:未付款 1:加团成功 2;超时  设置状态为 2;超时
                ptService.setPtMemberStatus(ptCaptain.getId(),2);
                log.info("【参团】{} 未满团 ，过期的参团订单已经在处理了，变更状态为2（超时）",ptCaptain.getProductId());
                // 发起退款
                aliRefundTuikuan(ptCaptain.getOrderId());

            } catch (Exception e) {
                log.error(e.getMessage());
                e.printStackTrace();
            }
        }
         **/

    }

    /**
     * 阿里支付退款公共方法
     * @param ptCaptain
     */
    private void aliRefundTuikuan(String orderId) {
        SysFlow sysFlow = sysOrderFlowService.findSysFlowByOrderId(orderId);
        SysOrder sysOrder = sysOrderFlowService.findSysOrderByOrderId(orderId);
        log.info("【发起退款】",sysFlow.toString());
        sysFlow.setOutRequestNo(UUidUtils.UID());// 系统退款号
        sysFlow.setFlowDesc("拼团订单超时发起退款");
        Map<String,String> alipayMap = aliPayService.aliRefund(sysFlow.getTrade_no(),sysFlow.getOrderId(),sysFlow.getOutRequestNo(),sysFlow.getPayAmount(),sysFlow.getFlowDesc());
        if (alipayMap.get("code").equals("200")) {
            log.info("{}执行退款订单{} 设置为3-退款；流水{} 设置2-已退款",sysOrder.getProductName(),sysOrder.getOrderId(),sysFlow.getFlowId());
            sysFlow.setIsPay(2);  // 支付：1-成功。2-退款
            sysOrder.setOrderStatus(3); // 订单状态；0-待支付，1-已支付，2-已过期，3-已退款
            log.info("支付宝退款成功");
        } else if (alipayMap.get("code").equals("400")){
            sysFlow.setIsPay(3);  // 支付：1-成功。2-退款.3-退款失败
            sysOrder.setOrderStatus(4); // 订单状态；0-待支付，1-已支付，2-已过期，3-已退款，4-退款失败
            sysFlow.setFlowDesc(alipayMap.get("message"));
            log.error("支付宝退款失败，原因：" + alipayMap.get("message"));
        }
        sysOrderFlowService.onlyAddOrder(sysOrder);
        sysOrderFlowService.addFlow(sysFlow);
    }

}